#include <QFile>
#include <QDir>

#include "romfs2.h"

romfs2::romfs2()
{

}

romfs2::~romfs2()
{

}

bool romfs2::mkimg(QString &path)
{
    if (isdir(path))
    {
        rilist_t list;

        mklist(path, list);
        do_mkimg(path, list);
    }
    else
    {
        errstr = "请放入目录";
        return false;
    }

    return true;
}

bool romfs2::do_mkimg(QString path, rilist_t &list)
{
    QByteArray entdata, fledata;
    struct romfs2_head *hdr;
    uint32_t pos;
    QByteArray buf(sizeof(*hdr), 0);
    romfs2_dirent *d;

    //head
    pos = sizeof(*hdr);
    hdr = (struct romfs2_head *)buf.data();

    hdr->magic = ROMFS2_MAGIC;
    hdr->root.pos = sizeof(*hdr) - sizeof(hdr->root);
    hdr->root.type = ROMFS2_ITEM_DIR;
    hdr->root.name[0] = '.';
    hdr->root.data = pos;
    hdr->root.size = list.count() * sizeof(struct romfs2_dirent);

    //dirent
    entdata.resize(hdr->root.size);
    d = (romfs2_dirent *)entdata.data();
    for (int i = 0; i < list.count(); i ++)
    {
        *d = list.at(i).dirent;
        d->pos = pos;
        d ++;
        pos += sizeof(struct romfs2_dirent);
    }

    //file data
    d = (romfs2_dirent *)entdata.data();
    for (int i = 0; i < list.count(); i ++)
    {
        struct romfs2_item ri;
        int padsize;

        ri = list.at(i);
        padsize = ri.data.size()%4;
        if (padsize != 0)
        {
            ri.data.append(4 - padsize, 0);
        }

        fledata += ri.data;
        d->data = pos;
        d ++;
        pos += ri.data.size();
    }

    //img
    hdr->volume = fledata.size();

    buf += entdata;
    buf += fledata;

    path += "/../romfs2.img";

    writefile(path, buf);

    errstr = "镜像:" + path;

    return true;
}

bool romfs2::writefile(QString &name, QByteArray &buf)
{
    QFile file(name);

    if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
        return false;

    file.write(buf);
    file.close();

    return true;
}

void romfs2::mklist(QString &name, rilist_t &list)
{
    QDir d(name);
    QStringList fl;

    fl = d.entryList();

    for (int i = 0; i < fl.count(); i ++)
    {
        QString e, fn;
        struct romfs2_item ri;

        e = fl.at(i);
        fn = name + "/" + e;
        if (!isdir(fn))
        {
            readfile(fn, ri.data);
            ri.dirent.type = ROMFS2_ITEM_FILE;
            ri.dirent.pos = 0;
            ri.dirent.size = ri.data.size();
            strncpy(ri.dirent.name,
                    e.toStdString().c_str(),
                    15);

            list.append(ri);
        }
    }

}

bool romfs2::isdir(QString &name)
{
    QDir d(name);

    return d.exists();
}

bool romfs2::readfile(QString &name, QByteArray &buf)
{
   QFile file(name);

   if (!file.open(QIODevice::ReadOnly))
       return false;

   buf = file.readAll();
   file.close();

   return true;
}
